package com.innovation.ic.sc.web.controller.sc;

import com.innovation.ic.b1b.framework.util.StringUtils;
import com.innovation.ic.sc.base.model.sc.Role;
import com.innovation.ic.sc.base.model.sc.User;
import com.innovation.ic.sc.base.pojo.constant.model.RoleAvailableStatus;
import com.innovation.ic.sc.base.pojo.constant.model.UserType;
import com.innovation.ic.sc.base.pojo.variable.ApiResult;
import com.innovation.ic.sc.base.pojo.variable.AuthenticationUser;
import com.innovation.ic.sc.base.pojo.variable.PageNationPojo;
import com.innovation.ic.sc.base.pojo.variable.ServiceResult;
import com.innovation.ic.sc.base.pojo.variable.menu.RolePojo;
import com.innovation.ic.sc.base.vo.menu.RoleVo;
import com.innovation.ic.sc.web.controller.AbstractController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色API
 */
@Api(value = "角色API", tags = "RoleController")
@RestController
@RequestMapping("/api/v1/role")
public class RoleController extends AbstractController {

    private static final Logger log = LoggerFactory.getLogger(RoleController.class);

    /**
     * 系统管理-职位管理-新增角色：创建角色，返回ObjectId的十六进制字符串
     *
     * @param roleVo
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-职位管理-新增角色：创建角色，返回ObjectId的十六进制字符串")
    @ApiImplicitParam(name = "roleVo", value = "角色", required = true, dataType = "RoleVo")
    @RequestMapping(value = "/saveRole", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<String>> save(@RequestBody RoleVo roleVo, HttpServletRequest request, HttpServletResponse response) {
        ApiResult<String> apiResult;

        if (null == roleVo) {
            String message = "调用接口【/api/v1/role/saveRole，参数roleVo不能为空";
            log.warn(message);
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }
        // 获取当前登录用户
        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }

        // 判断是否角色名称已经存在
        ServiceResult<Role> roleServiceResult = roleService.findByName(roleVo.getName(), authenticationUser.getId());
        if (null != roleServiceResult && null != roleServiceResult.getResult()) {
            String message = "角色已经存在，请重新设置";
            log.warn(message);
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.PARAMETER_DUPLICATE);
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        // 将RoleVo转换为Role
        Role role = modelHandler.roleVoToRole(roleVo, authenticationUser.getId());
        // 向mongodb中插入role
        ServiceResult<String> serviceResult = roleService.saveRole(role);

        apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(serviceResult.getResult());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 系统管理-职位管理-停用：根据id，改变角色的状态
     *
     * @param id
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-职位管理-停用：根据id，改变角色的状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "主键", dataType = "String", required = true),
            @ApiImplicitParam(name = "status", value = "角色的状态。1表示可用，2表示不可用", dataType = "Integer", required = true)
    })
    @RequestMapping(value = "/changeAvailableStatus/{id}/{status}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<Boolean>> changeAvailableStatus(@PathVariable("id") String id,
                                                                    @PathVariable("status") Integer status, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(id) || null == status) {
            String message = "调用接口【/changeAvailableStatus/{id}/{status}时，参数id和status不能为空";
            log.warn(message);
            ApiResult<Boolean> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        ServiceResult<Boolean> serviceResult = roleService.changeAvailableStatus(id, status);

        ApiResult<Boolean> apiResult = new ApiResult<>();
        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 系统管理-职位管理-修改：主账号修改角色名称和对应的菜单权限时，返回角色和对应的菜单树形目录（不包括账号管理和角色管理），其中有权限的菜单项被选中
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-职位管理-修改：主账号修改角色名称和对应的菜单权限时，返回角色和对应的菜单树形目录（不包括账号管理和角色管理），其中有权限的菜单项被选中")
    @RequestMapping(value = "/showMenuForUpdateRole", method = RequestMethod.POST, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<RolePojo>> showMenuForUpdateRole(@RequestBody RoleVo roleVo, HttpServletRequest request, HttpServletResponse response) {
        if (null == roleVo.get_id()) {
            String message = "调用接口【/api/v1/role/showMenuForUpdateRole时，参数roleVo不能为空";
            log.warn(message);
            ApiResult<RolePojo> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }
        if (!StringUtils.validateParameter(roleVo.get_id())) {
            String message = "调用接口【/api/v1/role/showMenuForUpdateRole时，参数_id不能为空";
            log.warn(message);
            ApiResult<RolePojo> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }
        // 获取当前登录用户
        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            ApiResult<RolePojo> apiResult = new ApiResult<>();
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }
        // 判断是否角色名称已经存在
        ServiceResult<Role> roleServiceResult = roleService.findByName(roleVo.getName(), authenticationUser.getId());
        if (null != roleServiceResult && null != roleServiceResult.getResult()) {
            if (!roleVo.get_id().equals(roleServiceResult.getResult().get_id().toString())) {
                String message = "角色已经存在，请重新设置";
                log.warn(message);
                ApiResult<RolePojo> apiResult = new ApiResult<>();
                apiResult = new ApiResult<>();
                apiResult.setSuccess(Boolean.FALSE);
                apiResult.setCode(ApiResult.PARAMETER_DUPLICATE);
                apiResult.setMessage(message);
                return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
            }
        }

        ServiceResult<Role> serviceResult = roleService.showMenuForUpdateRole(roleVo);

        Role role1 = serviceResult.getResult();
        ApiResult<RolePojo> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        if (role1 != null) {
            RolePojo rolePojo = new RolePojo();
            BeanUtils.copyProperties(role1, rolePojo);
            //需要转换id前端显示错误
            rolePojo.set_id(role1.get_id().toString());
            apiResult.setResult(rolePojo);
        }
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    @ApiOperation(value = "系统管理-职位管理-查询：查询角色名称和对应的菜单权限时，返回角色和对应的菜单树形目录（不包括账号管理和角色管理），其中有权限的菜单项被选中")
    @ApiImplicitParam(name = "roleId", value = "角色id", required = true, dataType = "String")
    @RequestMapping(value = "/showMenuForRoleById/{roleId}", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<RolePojo>> showMenuForRoleById(@PathVariable("roleId") String roleId, HttpServletRequest request, HttpServletResponse response) {
        if (!StringUtils.validateParameter(roleId)) {
            String message = "调用接口【/api/v1/role/showMenuForRoleById/{roleId}时，参数roleId不能为空";
            log.warn(message);
            ApiResult<RolePojo> apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(HttpStatus.BAD_REQUEST.value());
            apiResult.setMessage(message);
            return new ResponseEntity<>(apiResult, HttpStatus.BAD_REQUEST);
        }

        ServiceResult<Role> serviceResult = roleService.showMenuForRoleById(roleId);
        Role role = serviceResult.getResult();
        ApiResult<RolePojo> apiResult = new ApiResult<>();
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        if (role != null) {
            RolePojo rolePojo = new RolePojo();
            BeanUtils.copyProperties(role, rolePojo);
            //需要转换id前端显示错误
            rolePojo.set_id(role.get_id().toString());
            apiResult.setResult(rolePojo);
        }
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }

    /**
     * 系统管理-账号管理-权限设置-角色下拉列表：查找所有角色（包括可用的和不可用的）。前端需要根据available字段来判断是否可用。
     * 系统管理-职位管理：查找所有角色（包括可用的和不可用的）。
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-账号管理-权限设置-角色下拉列表：查找所有角色（包括可用的和不可用的）。前端需要根据available字段来判断是否可用。" +
            "系统管理-职位管理：查找所有角色（包括可用的和不可用的）。")
    @RequestMapping(value = "/findAll", method = RequestMethod.GET, produces = {"application/json; charset=utf-8"})
    @ResponseBody
    public ResponseEntity<ApiResult<List<RolePojo>>> findAll(HttpServletRequest request, HttpServletResponse response) {
        ApiResult<List<RolePojo>> apiResult = new ApiResult<>();
        // 获取当前登录用户
        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }
        //获取主账号id
        String userMainId = null;
        if (authenticationUser.getIsMain() != null && authenticationUser.getIsMain().equals(UserType.MAIN_ACCOUNT)) {
            userMainId = authenticationUser.getId();
        } else {
            ServiceResult<User> byUserId = userService.findByUserId(authenticationUser.getId());
            User user = byUserId.getResult();
            if (user != null && StringUtils.isNotEmpty(user.getFatherId())) {
                userMainId = user.getFatherId();
            }
        }
        //处理
        List<RolePojo> rolePojoList = null;
        if (StringUtils.isEmpty(userMainId)) {
            apiResult.setSuccess(true);
            apiResult.setCode(HttpStatus.OK.value());
            apiResult.setResult(rolePojoList);
            return new ResponseEntity<>(apiResult, HttpStatus.OK);
        }

        ServiceResult<List<Role>> serviceResult = roleService.findAllByUserId(userMainId);
        rolePojoList = serviceResult.getResult().stream().filter(role -> RoleAvailableStatus.YES.equals(role.getAvailable())).map(role -> {
            RolePojo rolePojo = new RolePojo();
            BeanUtils.copyProperties(role, rolePojo);
            //需要转换id前端显示错误
            rolePojo.set_id(role.get_id().toString());
            return rolePojo;
        }).collect(Collectors.toList());

        apiResult.setSuccess(serviceResult.getSuccess());
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(serviceResult.getMessage());
        apiResult.setResult(rolePojoList);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }


    /**
     * 系统管理-账号管理-权限设置-角色下拉列表：查找所有角色（包括可用的和不可用的）。前端需要根据available字段来判断是否可用。
     * 系统管理-职位管理：查找所有角色（包括可用的和不可用的）。
     *
     * @param request
     * @param response
     * @return
     */
//    @HystrixCommand
    @ApiOperation(value = "系统管理-账号管理-角色管理：分页查找所有角色（包括可用的和不可用的）。前端需要根据available字段来判断是否可用。" +
            "系统管理-职位管理：查找所有角色（包括可用的和不可用的）。")
    @GetMapping(value = "/pageFindAll/{pageNo}/{pageSize}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页数", dataType = "Integer", required = true, defaultValue = "1"),
            @ApiImplicitParam(name = "pageSize", value = "每页数量", dataType = "Integer", required = true, defaultValue = "20")
    })
    @ResponseBody
    public ResponseEntity<ApiResult<PageNationPojo<RolePojo>>> pageFindAll(@PathVariable("pageNo") Integer pageNo,
                                                                           @PathVariable("pageSize") Integer pageSize,
                                                                           HttpServletRequest request,
                                                                           HttpServletResponse response) {
        ApiResult<PageNationPojo<RolePojo>> apiResult = new ApiResult<>();
        // 获取当前登录用户
        AuthenticationUser authenticationUser = this.getAuthenticationUser(request);
        if (null == authenticationUser) {
            apiResult = new ApiResult<>();
            apiResult.setSuccess(Boolean.FALSE);
            apiResult.setCode(ApiResult.TOKEN_ILLEGAL_EXPIRE);
            return new ResponseEntity(apiResult, HttpStatus.UNAUTHORIZED);
        }
        //获取主账号id
        String userMainId = null;
        if (authenticationUser.getIsMain() != null && authenticationUser.getIsMain().equals(UserType.MAIN_ACCOUNT)) {
            userMainId = authenticationUser.getId();
        } else {
            ServiceResult<User> byUserId = userService.findByUserId(authenticationUser.getId());
            User user = byUserId.getResult();
            if (user != null && StringUtils.isNotEmpty(user.getFatherId())) {
                userMainId = user.getFatherId();
            }
        }
        //处理
        List<RolePojo> rolePojoList = null;
        if (StringUtils.isEmpty(userMainId)) {
            apiResult.setSuccess(true);
            apiResult.setCode(HttpStatus.OK.value());
            apiResult.setResult(null);
            return new ResponseEntity<>(apiResult, HttpStatus.OK);
        }

        PageNationPojo<RolePojo> rolePage = roleService.pageFindAllByUserId(userMainId, pageNo, pageSize);
        apiResult.setSuccess(Boolean.TRUE);
        apiResult.setCode(HttpStatus.OK.value());
        apiResult.setMessage(ServiceResult.SELECT_SUCCESS);
        apiResult.setResult(rolePage);
        return new ResponseEntity<>(apiResult, HttpStatus.OK);
    }


}
